<!DOCTYPE html>
<html>
  <head>
    <!-- Update title -->
    <title>Flocking: Part 3</title>

    <!-- keywords used for searching -->
    <meta name="keywords" content="guide, flocking, particles">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- reference to Cinder classes -->
      <!-- <ci seealso dox="[CLASS NAME GOES HERE]" label="[NAME OF LINK]"></ci> -->

      <!-- master stylesheet - these links will be replaced when compiled -->
    <link rel="stylesheet" href="../../_assets/css/foundation.css">
    <link rel="stylesheet" href="../../_assets/css/prism.css">
    <link rel="stylesheet" href="../../_assets/css/style.css">
    <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700' rel='stylesheet' type='text/css'>

    <!-- Place additional stylsheet links here, which will be copied over when compiled (optional) -->
    
  </head>

  <body id="guide-contents" class="language-c++">

    <!-- CONTENT STARTS HERE -->
    <h1><a class="anchor" id="cohesion"></a>
    RULE 2: COHESION (Avoid isolation)</h1>
    <p><br />
    </p><div class="image">
    <img src="images/rule2.jpg" alt="rule2.jpg"/>
    </div>
    <p> <br />
    <br />
    In the last chapter, we discussed the first rule of Flocking: avoid overcrowding (separation). Now we are going to talk about the complement. Rule 2 roughly states that if you find yourself out on your own, move towards your neighbors. In the harsh reality of the predator-prey relationship, those that wander away or get separated from the group are the ones that are eaten. Follow Rule 2. It could save your life. <br />
     <br />
     

    <div class="fragment"><pre class="fragment"><span style="font-size: x-small;">void ParticleController::applyForce( float zoneRadiusSqrd, float thresh )
    {
      for( list::iterator p1 = mParticles.begin(); p1 != mParticles.end(); ++p1 ) {
        list::iterator p2 = p1;
        for( ++p2; p2 != mParticles.end(); ++p2 ) {
          Vec3f dir = p1-&gt;mPos - p2-&gt;mPos;
          float distSqrd = dir.lengthSquared();

          if( distSqrd &lt; zoneRadiusSqrd ) { // If the neighbor is within the zone radius...
            float percent = distSqrd/zoneRadiusSqrd;

            if( percent &lt; thresh ) { // ... and is within the threshold limits, separate...
              <span style="color: #3366ff;">float F = ( thresh/percent - 1.0f ) * 0.01f;
              dir = dir.normalized() * F;
              p1-&gt;mAcc += dir;
              p2-&gt;mAcc -= dir;</span>
            }
            else { // ... else attract
              <span style="color: #ff0000;">float threshDelta = 1.0f - thresh;
              float adjustedPercent = ( percent - thresh )/threshDelta;
              float F = ( 1.0 - ( cos( adjustedPercent * M_PI*2.0f ) * -0.5f + 0.5f ) ) * 0.04f;
              dir = dir.normalized() * F;
              p1-&gt;mAcc -= dir;
              p2-&gt;mAcc += dir;</span>
            }
          }
        }
      }
    }</span></pre></div>

    </p>
    <p><br />
    We still have the nested for-loop of list iterators from the last chapter. The thing that has changed is we now have an additional case for our distance (squared) checks. If the squared distance between two <em>Particle</em>s is less than the threshold, then we want to repel. If the squared distance is greater, then we apply the attraction force. <br />
     <br />
    The reason we bother with this upper threshold limit (the zone radius) is two-fold. It is much more likely that flocking creatures pay attention to their nearest few neighbors as opposed to taking in the position of every single neighbor. In a <a href="http://www.youtube.com/watch?v=XH-groCeKbE">flock of starlings</a>, for example, it is theorized that <a href="http://www.audubonmagazine.org/features0903/truenature.html">each bird pays attention to 6 or 7 neighbors</a>. Luckily for us, to only pay attention to a handful of neighbors eases the load on the processor. Sadly, we are still doing distance (squared) checks which we need for the threshold comparison, but at least we can rule out distant objects and not worry about the extra math in that if-else statement. (note: There are many ways to deal with this work load that would improve the performance dramatically, such as implementing a <a href="http://en.wikipedia.org/wiki/Kd-tree">kd-tree</a> or <a href="http://en.wikipedia.org/wiki/Octree">Octree</a>. However, this will unnecessarily complicate the tutorial so we will leave that for a future chapter or as an exercise for the reader.) <br />
     <br />
    I would like to draw attention to the Force variable again. It is without question the most confusing line in the <em>applyForce() </em>method. <br />
     <br />
    </p><div class="fragment"><div class="line"><span class="keywordtype">float</span> F = ( 1.0 - ( cos( adjustedPercent * <a class="code" href="_cinder_math_8h.html#ae71449b1cc6e6250b91f539153a7a0d3">M_PI</a> * 2.0f ) * -0.5f + 0.5f ) ) * 0.04f;</div>
    </div><!-- fragment --><p><br />
    If you look at the <em>adjustedPercent</em> variable, you should notice that it is normalizing the range that the percent variable can exist within. Basically, <em>adjustedPercent</em> is a variable that has a range from <em>0.0</em> to <em>1.0</em>. Inside the <em>cos()</em>, we multiply our adjusted percentage by<em> 2&pi;</em> so now we have a range from <em>0.0</em> to<em> 2&pi;</em>. <br />
     <br />
    Take a look at the picture below. The upper curve is what we have: cosine between <em>0.0</em> and<em> 2&pi; </em> which creates a smooth undulation from <em>1.0</em> to <em>-1.0</em> and back to <em>1.0</em>. However, we want a curve we can use to control how much each particle attracts each other particle within the range. To do that, we need to turn the original curve into one that undulates from <em>0.0</em> to <em>1.0</em> and back to <em>0.0</em>. All the Force equation is doing is finding a way to take our BEFORE curve and turn it into our AFTER curve. <br />
     <br />
    </p><div class="image">
    <img src="images/cos.jpg" alt="cos.jpg"/>
    </div>
    <p> <br />
     <br />
    The reason we want to do this is so we can have a smooth transition as the neighbor particle goes from outside the range to inside the range. Otherwise, the particle movements through space would be more jarring and angular. We want smooth and blended movement. That is all the Force equation is doing. <br />
     <br />
    Think of it this way. The height of the black curve below shows the strength of the force at every position in the zone radius. The attractive force right on the very edge of the zone radius is zero, as it is right where the zone transitions from separation to cohesion. <br />
     <br />
    </p><div class="image">
    <img src="images/curve2.jpg" alt="curve2.jpg"/>
    </div>
    <p> <br />
     <br />
    As I mentioned in the last chapter, a large percentage of time is spent tweaking the <em>F</em> variable for the repulsion and attraction equations. If the attractive force is too strong, the flockers bunch up and resemble a swarm of gnats or flies. If the attractive force is too weak, the flockers barely seem to flock at all. <br />
     <br />
    When you run the project, you will notice the difference between Chapter 2 and Chapter 3 isn't too pronounced. This is because we already added an attractive force in Chapter 1 in the form of the global gravitation towards the center of the screen. With the introduction of <em>Particle</em>-to-<em>Particle</em> attraction in this chapter, we don't really need that global gravitation as much as before. Since the <em>Particle</em>s are pulling towards each other, they tend to want to hang out in a big group. If we turn off the gravity, the <em>Particle</em>s will hover around the center of the screen for a while but will eventually wander and disappear from view. <br />
     <br />
    </p><div class="image">
    <img src="images/chapter3a.jpg" alt="chapter3a.jpg"/>
    </div>
    <p> <br />
     <br />
    However, we did add a new boolean toggle called <em>mFlatten</em>. As you might imagine, turning on the flatten feature squashes the z-axis down to zero so you can better see how the <em>Particle</em>s are pushing each other around. It is very useful for fine-tuning your force equations. <br />
     <br />
    </p><div class="image">
    <img src="images/chapter3b.jpg" alt="chapter3b.jpg"/>
    </div>
    <p> <br />
     <br />
    In <a class="el" href="chapter4.html">Flocking Chapter 4</a>, the third rule for the flocking system is explained. It is the rule of alignment which helps the particles behave as a group.</p>
    <p><br />
    </p>
    <!-- END CONTENT -->

    <!-- Scripts -->
    <script src="../../_assets/js/prism.js" type="text/javascript"></script>
    <!-- Place additional scripts here (optional) -->
    <!-- <script type="text/javascript"></script> -->

  </body>
</html> 